<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: ipc::session::Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; Class Template Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;1.0.2</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceipc.html">ipc</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1session.html">session</a></li><li class="navelem"><a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-types">Public Types</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pri-types">Private Types</a> &#124;
<a href="#related">Related Functions</a> &#124;
<a href="classipc_1_1session_1_1Session__server-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">ipc::session::Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; Class Template Reference</div></div>
</div><!--header-->
<div class="contents">

<p>To be instantiated typically once in a given process, an object of this type asynchronously listens for <a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a> processes each of which wishes to establish a <em>session</em> with this server process; emits resulting Server_session objects locally.  
 <a href="classipc_1_1session_1_1Session__server.html#details">More...</a></p>

<p><code>#include &lt;<a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for ipc::session::Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classipc_1_1session_1_1Session__server__inherit__graph.svg" width="619" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for ipc::session::Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classipc_1_1session_1_1Session__server__coll__graph.svg" width="1294" height="432"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-types" name="pub-types"></a>
Public Types</h2></td></tr>
<tr class="memitem:a4140ba69205b68aec322ad834f4c8d59"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59">Server_session_obj</a> = <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc">Server_session</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;</td></tr>
<tr class="memdesc:a4140ba69205b68aec322ad834f4c8d59"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for the concrete <code>Server_session</code>-like type emitted by <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>.  <a href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59">More...</a><br /></td></tr>
<tr class="separator:a4140ba69205b68aec322ad834f4c8d59"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa19b9057ac2d873b5989b6213a9e6f82"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#aa19b9057ac2d873b5989b6213a9e6f82">Mdt_reader_ptr</a> = typename Impl::Mdt_reader_ptr</td></tr>
<tr class="memdesc:aa19b9057ac2d873b5989b6213a9e6f82"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for <a class="el" href="classipc_1_1session_1_1Session__mv.html#a2b1215fb0c9738b9fcfbb337d23c43df" title="Implements Session API per contract.">Session_mv::Mdt_reader_ptr</a>.  <a href="classipc_1_1session_1_1Session__server.html#aa19b9057ac2d873b5989b6213a9e6f82">More...</a><br /></td></tr>
<tr class="separator:aa19b9057ac2d873b5989b6213a9e6f82"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a86e894429b8568458aa20f3ba814434d"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a86e894429b8568458aa20f3ba814434d">Mdt_builder</a> = typename <a class="el" href="classipc_1_1session_1_1Session__mv.html#af10f452e602e4ea7389c6a77dd9a0f88">Server_session_obj::Mdt_builder</a></td></tr>
<tr class="memdesc:a86e894429b8568458aa20f3ba814434d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Metadata builder type passed to <code>mdt_load_func()</code> in advanced <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload.  <a href="classipc_1_1session_1_1Session__server.html#a86e894429b8568458aa20f3ba814434d">More...</a><br /></td></tr>
<tr class="separator:a86e894429b8568458aa20f3ba814434d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6dea741c32a771532a884ffbc0826bb3"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a6dea741c32a771532a884ffbc0826bb3">Channels</a> = typename Impl::Channels</td></tr>
<tr class="memdesc:a6dea741c32a771532a884ffbc0826bb3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for <a class="el" href="classipc_1_1session_1_1Session__mv.html#af87da439644b2afd73d6a13d97e7985f" title="Container (vector&lt;&gt;) of Channel_obj.">Session_mv::Channels</a>.  <a href="classipc_1_1session_1_1Session__server.html#a6dea741c32a771532a884ffbc0826bb3">More...</a><br /></td></tr>
<tr class="separator:a6dea741c32a771532a884ffbc0826bb3"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a948ef778f6dd521e0f7632e9f7e06aa7"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a948ef778f6dd521e0f7632e9f7e06aa7">Session_server</a> (flow::log::Logger *logger_ptr, const <a class="el" href="structipc_1_1session_1_1Server__app.html">Server_app</a> &amp;srv_app_ref, const <a class="el" href="structipc_1_1session_1_1Client__app.html#add718cbf6aa1d2abb26fbadcc974a7bd">Client_app::Master_set</a> &amp;cli_app_master_set_ref, <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code=0)</td></tr>
<tr class="memdesc:a948ef778f6dd521e0f7632e9f7e06aa7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructor: immediately begins listening for incoming session-open attempts from allowed clients.  <a href="classipc_1_1session_1_1Session__server.html#a948ef778f6dd521e0f7632e9f7e06aa7">More...</a><br /></td></tr>
<tr class="separator:a948ef778f6dd521e0f7632e9f7e06aa7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae9c7c3132edba73bfad5d5a90722e813"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#ae9c7c3132edba73bfad5d5a90722e813">~Session_server</a> ()</td></tr>
<tr class="memdesc:ae9c7c3132edba73bfad5d5a90722e813"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroys this acceptor which will stop listening in the background and cancel any pending completion handlers by invoking them ASAP with <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fafe29343445a7bf167cc186a44bd2c6ed" title="Async completion handler is being called prematurely, because underlying object is shutting down,...">session::error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER</a>.  <a href="classipc_1_1session_1_1Session__server.html#ae9c7c3132edba73bfad5d5a90722e813">More...</a><br /></td></tr>
<tr class="separator:ae9c7c3132edba73bfad5d5a90722e813"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a13887cd64912bb5f5675e2817ff8435f"><td class="memTemplParams" colspan="2">template&lt;typename Task_err &gt; </td></tr>
<tr class="memitem:a13887cd64912bb5f5675e2817ff8435f"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f">async_accept</a> (<a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59">Server_session_obj</a> *target_session, Task_err &amp;&amp;on_done_func)</td></tr>
<tr class="memdesc:a13887cd64912bb5f5675e2817ff8435f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Asynchronously awaits for an opposing Client_session to request session establishment and calls <code>on_done_func()</code>, once the connection occurs and log-in exchange completes, or an error occurs, in the former case move-assigning an almost-PEER-state Server_session object to the passed-in Server_session <code>*target_session</code>.  <a href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f">More...</a><br /></td></tr>
<tr class="separator:a13887cd64912bb5f5675e2817ff8435f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aee11a4a3e305bd3aa330f99fe5a9c509"><td class="memTemplParams" colspan="2">template&lt;typename Task_err , typename N_init_channels_by_srv_req_func , typename Mdt_load_func &gt; </td></tr>
<tr class="memitem:aee11a4a3e305bd3aa330f99fe5a9c509"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#aee11a4a3e305bd3aa330f99fe5a9c509">async_accept</a> (<a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59">Server_session_obj</a> *target_session, <a class="el" href="classipc_1_1session_1_1Session__server.html#a6dea741c32a771532a884ffbc0826bb3">Channels</a> *init_channels_by_srv_req, <a class="el" href="classipc_1_1session_1_1Session__server.html#aa19b9057ac2d873b5989b6213a9e6f82">Mdt_reader_ptr</a> *mdt_from_cli_or_null, <a class="el" href="classipc_1_1session_1_1Session__server.html#a6dea741c32a771532a884ffbc0826bb3">Channels</a> *init_channels_by_cli_req, N_init_channels_by_srv_req_func &amp;&amp;n_init_channels_by_srv_req_func, Mdt_load_func &amp;&amp;mdt_load_func, Task_err &amp;&amp;on_done_func)</td></tr>
<tr class="memdesc:aee11a4a3e305bd3aa330f99fe5a9c509"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to the simpler <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload but offers added advanced capabilities: metadata exchange; initial-channel opening.  <a href="classipc_1_1session_1_1Session__server.html#aee11a4a3e305bd3aa330f99fe5a9c509">More...</a><br /></td></tr>
<tr class="separator:aee11a4a3e305bd3aa330f99fe5a9c509"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5fac8f78f1ff443db9b46788cae77fc4"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a5fac8f78f1ff443db9b46788cae77fc4">to_ostream</a> (std::ostream *os) const</td></tr>
<tr class="memdesc:a5fac8f78f1ff443db9b46788cae77fc4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation to the given <code>ostream</code>.  <a href="classipc_1_1session_1_1Session__server.html#a5fac8f78f1ff443db9b46788cae77fc4">More...</a><br /></td></tr>
<tr class="separator:a5fac8f78f1ff443db9b46788cae77fc4"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-types" name="pri-types"></a>
Private Types</h2></td></tr>
<tr class="memitem:a88662c940c51cbaad4dd2cc8af87b147"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a88662c940c51cbaad4dd2cc8af87b147">Impl</a> = <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">Session_server_impl</a>&lt; <a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;, <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc">Server_session</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &gt;</td></tr>
<tr class="memdesc:a88662c940c51cbaad4dd2cc8af87b147"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for our base/core impl.  <a href="classipc_1_1session_1_1Session__server.html#a88662c940c51cbaad4dd2cc8af87b147">More...</a><br /></td></tr>
<tr class="separator:a88662c940c51cbaad4dd2cc8af87b147"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_types_classipc_1_1session_1_1Session__server__impl"><td colspan="2" onclick="javascript:toggleInherit('pub_types_classipc_1_1session_1_1Session__server__impl')"><img src="closed.png" alt="-"/>&#160;Private Types inherited from <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">ipc::session::Session_server_impl&lt; Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;, Server_session&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &gt;</a></td></tr>
<tr class="memitem:a47625f247dea35cf276d31c039c6bf0c inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a47625f247dea35cf276d31c039c6bf0c">Session_server_obj</a> = <a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;</td></tr>
<tr class="memdesc:a47625f247dea35cf276d31c039c6bf0c inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">See <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#ad7cd4d77db826af9fe39c17e8ee7ca37" title="Returns pointer to the object that is privately sub-classing us.">this_session_srv()</a>.  <a href="classipc_1_1session_1_1Session__server__impl.html#a47625f247dea35cf276d31c039c6bf0c">More...</a><br /></td></tr>
<tr class="separator:a47625f247dea35cf276d31c039c6bf0c inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0009247dd98ec58b22040d1c65bb5a54 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a0009247dd98ec58b22040d1c65bb5a54">Server_session_obj</a> = <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc">Server_session</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;</td></tr>
<tr class="memdesc:a0009247dd98ec58b22040d1c65bb5a54 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">Useful short-hand for the concrete <code>Server_session</code> type emitted by <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a60ec88b23d73c354959a1e11636dc717" title="See Session_server method.">async_accept()</a>.  <a href="classipc_1_1session_1_1Session__server__impl.html#a0009247dd98ec58b22040d1c65bb5a54">More...</a><br /></td></tr>
<tr class="separator:a0009247dd98ec58b22040d1c65bb5a54 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a86de1d5b7cae35d89827c3235e2b8d89 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a86de1d5b7cae35d89827c3235e2b8d89">Mdt_reader_ptr</a> = typename <a class="el" href="classipc_1_1session_1_1Session__mv.html#a2b1215fb0c9738b9fcfbb337d23c43df">Server_session_obj::Mdt_reader_ptr</a></td></tr>
<tr class="memdesc:a86de1d5b7cae35d89827c3235e2b8d89 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for Session_mv::Mdt_reader_ptr.  <a href="classipc_1_1session_1_1Session__server__impl.html#a86de1d5b7cae35d89827c3235e2b8d89">More...</a><br /></td></tr>
<tr class="separator:a86de1d5b7cae35d89827c3235e2b8d89 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9ad5c6cbb1c9378d42ec5cd909389dc2 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a9ad5c6cbb1c9378d42ec5cd909389dc2">Channels</a> = typename <a class="el" href="classipc_1_1session_1_1Session__mv.html#af87da439644b2afd73d6a13d97e7985f">Server_session_obj::Channels</a></td></tr>
<tr class="memdesc:a9ad5c6cbb1c9378d42ec5cd909389dc2 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for Session_mv::Channels.  <a href="classipc_1_1session_1_1Session__server__impl.html#a9ad5c6cbb1c9378d42ec5cd909389dc2">More...</a><br /></td></tr>
<tr class="separator:a9ad5c6cbb1c9378d42ec5cd909389dc2 inherit pub_types_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="related" name="related"></a>
Related Functions</h2></td></tr>
<tr><td class="ititle" colspan="2"><p >(Note that these are not member functions.) </p>
</td></tr>
<tr class="memitem:a4556b229bf2bfc3c9eb51af13c47de3d"><td class="memTemplParams" colspan="2">template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </td></tr>
<tr class="memitem:a4556b229bf2bfc3c9eb51af13c47de3d"><td class="memTemplItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server.html#a4556b229bf2bfc3c9eb51af13c47de3d">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &amp;val)</td></tr>
<tr class="memdesc:a4556b229bf2bfc3c9eb51af13c47de3d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <code><a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a></code> to the given <code>ostream</code>.  <a href="classipc_1_1session_1_1Session__server.html#a4556b229bf2bfc3c9eb51af13c47de3d">More...</a><br /></td></tr>
<tr class="separator:a4556b229bf2bfc3c9eb51af13c47de3d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header related_classipc_1_1session_1_1Session__server__impl"><td colspan="2" onclick="javascript:toggleInherit('related_classipc_1_1session_1_1Session__server__impl')"><img src="closed.png" alt="-"/>&#160;Related Functions inherited from <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">ipc::session::Session_server_impl&lt; Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;, Server_session&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &gt;</a></td></tr>
<tr class="memitem:a5fc42e333522f7b1ed11fbff4ae72e5c inherit related_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a5fc42e333522f7b1ed11fbff4ae72e5c">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">Session_server_impl</a>&lt; <a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;, <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc">Server_session</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &gt; &amp;val)</td></tr>
<tr class="memdesc:a5fc42e333522f7b1ed11fbff4ae72e5c inherit related_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <code>Session_server_impl</code> to the given <code>ostream</code>.  <a href="classipc_1_1session_1_1Session__server__impl.html#a5fc42e333522f7b1ed11fbff4ae72e5c">More...</a><br /></td></tr>
<tr class="separator:a5fc42e333522f7b1ed11fbff4ae72e5c inherit related_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="inherited" name="inherited"></a>
Additional Inherited Members</h2></td></tr>
<tr class="inherit_header pub_methods_classipc_1_1session_1_1Session__server__impl"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classipc_1_1session_1_1Session__server__impl')"><img src="closed.png" alt="-"/>&#160;Private Member Functions inherited from <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">ipc::session::Session_server_impl&lt; Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;, Server_session&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &gt;</a></td></tr>
<tr class="memitem:a9bf4d5502b41c98a98fee4cc3c2f2530 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a9bf4d5502b41c98a98fee4cc3c2f2530">Session_server_impl</a> (flow::log::Logger *logger_ptr, <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a47625f247dea35cf276d31c039c6bf0c">Session_server_obj</a> *this_session_srv_arg, const <a class="el" href="structipc_1_1session_1_1Server__app.html">Server_app</a> &amp;srv_app_ref, const <a class="el" href="structipc_1_1session_1_1Client__app.html#add718cbf6aa1d2abb26fbadcc974a7bd">Client_app::Master_set</a> &amp;cli_app_master_set_ref, <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code, Per_app_setup_func &amp;&amp;per_app_setup_func)</td></tr>
<tr class="memdesc:a9bf4d5502b41c98a98fee4cc3c2f2530 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">See Session_server ctor; it does that.  <a href="classipc_1_1session_1_1Session__server__impl.html#a9bf4d5502b41c98a98fee4cc3c2f2530">More...</a><br /></td></tr>
<tr class="separator:a9bf4d5502b41c98a98fee4cc3c2f2530 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae4388def520aad700a3fcdfc95b6f24e inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#ae4388def520aad700a3fcdfc95b6f24e">~Session_server_impl</a> ()</td></tr>
<tr class="memdesc:ae4388def520aad700a3fcdfc95b6f24e inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">See Session_server dtor.  <a href="classipc_1_1session_1_1Session__server__impl.html#ae4388def520aad700a3fcdfc95b6f24e">More...</a><br /></td></tr>
<tr class="separator:ae4388def520aad700a3fcdfc95b6f24e inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a60ec88b23d73c354959a1e11636dc717 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a60ec88b23d73c354959a1e11636dc717">async_accept</a> (<a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a0009247dd98ec58b22040d1c65bb5a54">Server_session_obj</a> *target_session, <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a9ad5c6cbb1c9378d42ec5cd909389dc2">Channels</a> *init_channels_by_srv_req, <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a86de1d5b7cae35d89827c3235e2b8d89">Mdt_reader_ptr</a> *mdt_from_cli_or_null, <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a9ad5c6cbb1c9378d42ec5cd909389dc2">Channels</a> *init_channels_by_cli_req, N_init_channels_by_srv_req_func &amp;&amp;n_init_channels_by_srv_req_func, Mdt_load_func &amp;&amp;mdt_load_func, Task_err &amp;&amp;on_done_func)</td></tr>
<tr class="memdesc:a60ec88b23d73c354959a1e11636dc717 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">See Session_server method.  <a href="classipc_1_1session_1_1Session__server__impl.html#a60ec88b23d73c354959a1e11636dc717">More...</a><br /></td></tr>
<tr class="separator:a60ec88b23d73c354959a1e11636dc717 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2a3c0c330d477176b714a9920196775d inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a2a3c0c330d477176b714a9920196775d">to_ostream</a> (std::ostream *os) const</td></tr>
<tr class="memdesc:a2a3c0c330d477176b714a9920196775d inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">See Server_session method.  <a href="classipc_1_1session_1_1Session__server__impl.html#a2a3c0c330d477176b714a9920196775d">More...</a><br /></td></tr>
<tr class="separator:a2a3c0c330d477176b714a9920196775d inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad7cd4d77db826af9fe39c17e8ee7ca37 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a47625f247dea35cf276d31c039c6bf0c">Session_server_obj</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#ad7cd4d77db826af9fe39c17e8ee7ca37">this_session_srv</a> ()</td></tr>
<tr class="memdesc:ad7cd4d77db826af9fe39c17e8ee7ca37 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns pointer to the object that is <code>private</code>ly sub-classing us.  <a href="classipc_1_1session_1_1Session__server__impl.html#ad7cd4d77db826af9fe39c17e8ee7ca37">More...</a><br /></td></tr>
<tr class="separator:ad7cd4d77db826af9fe39c17e8ee7ca37 inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a40fca0b878f9150f5f7db55768da45ad inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a40fca0b878f9150f5f7db55768da45ad">sub_class_set_deinit_func</a> (Task &amp;&amp;task)</td></tr>
<tr class="memdesc:a40fca0b878f9150f5f7db55768da45ad inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">Utility for sub-classes: ensures that <code>task()</code> is invoked near the end of <code>*this</code> dtor's execution, after <em>all</em> other (mutable) state has been destroyed, including stopping/joining any threads performing async <a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a60ec88b23d73c354959a1e11636dc717" title="See Session_server method.">async_accept()</a> ops.  <a href="classipc_1_1session_1_1Session__server__impl.html#a40fca0b878f9150f5f7db55768da45ad">More...</a><br /></td></tr>
<tr class="separator:a40fca0b878f9150f5f7db55768da45ad inherit pub_methods_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_attribs_classipc_1_1session_1_1Session__server__impl"><td colspan="2" onclick="javascript:toggleInherit('pub_attribs_classipc_1_1session_1_1Session__server__impl')"><img src="closed.png" alt="-"/>&#160;Private Attributes inherited from <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">ipc::session::Session_server_impl&lt; Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;, Server_session&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &gt;</a></td></tr>
<tr class="memitem:a7be0cca184cdba62b9748e0ca37b8b17 inherit pub_attribs_classipc_1_1session_1_1Session__server__impl"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="structipc_1_1session_1_1Server__app.html">Server_app</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1session_1_1Session__server__impl.html#a7be0cca184cdba62b9748e0ca37b8b17">m_srv_app_ref</a></td></tr>
<tr class="memdesc:a7be0cca184cdba62b9748e0ca37b8b17 inherit pub_attribs_classipc_1_1session_1_1Session__server__impl"><td class="mdescLeft">&#160;</td><td class="mdescRight">See Session_server public data member.  <a href="classipc_1_1session_1_1Session__server__impl.html#a7be0cca184cdba62b9748e0ca37b8b17">More...</a><br /></td></tr>
<tr class="separator:a7be0cca184cdba62b9748e0ca37b8b17 inherit pub_attribs_classipc_1_1session_1_1Session__server__impl"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><div class="compoundTemplParams">template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload&gt;<br />
class ipc::session::Session_server&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;</div><p >To be instantiated typically once in a given process, an object of this type asynchronously listens for <a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a> processes each of which wishes to establish a <em>session</em> with this server process; emits resulting Server_session objects locally. </p>
<h3>When to use</h3>
<p >In the <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> paradigm: See <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a> doc header "When to use" section. If and only if, based on that text, you wish to use this application to instantiate <code>Server_session</code>s, then you must instantiate a single <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> to emit them. (It is not possible to directly construct a PEER-state &ndash; i.e., at all useful &ndash; <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a>.)</p>
<p >Note that while in a typical (non-test/debug) scenario one would only instantiate a single <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a>, that does <em>not</em> mean it cannot or should not instantiate <code>Client_session</code>s as well. In a <em>given</em> split, a given application is either the server or the client; but in a different split it be the other thing. So a <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> handles all the splits in which this application is the server; but for other splits one would instantiate 0+ <code>Client_session</code>s separately.</p>
<h3>How to use</h3>
<p >Similarly to <a class="el" href="classipc_1_1transport_1_1Native__socket__stream__acceptor.html" title="A server object that binds to a Shared_name and listens for incoming Native_socket_stream connect att...">transport::Native_socket_stream_acceptor</a> constructing <code>*this</code> immediately async-listens to incoming connections (each an attempt to establish a opposing Client_session to partner with a new local <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a>). <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> shall accept such connections, one at a time, in FIFO order (including any that may have queued up in the meantime, including after mere construction). The meaning of FIFO order is discussed below.</p>
<p >Once a <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a> is emitted to a handler passed to <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>, refer to <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a> doc header for how to operate it. Spoiler alert: you must still call <code><a class="el" href="classipc_1_1session_1_1Server__session__mv.html#a99097e5aa6883877c74f8a93ebc9f3e1" title="To be invoked by public user upon first obtaining *this: memorizes the given on-error and on-passive-...">Server_session::init_handlers()</a></code>; at which point the <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a> is a <a class="el" href="classipc_1_1session_1_1Session.html" title="A documentation-only concept defining the local side of an IPC conversation (session) with another en...">Session</a> concept impl in PEER state.</p>
<h3>Error handling</h3>
<p >The model followed is the typical boost.asio-like one: Each <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> takes a handler, F, and it is eventually invoked no matter what: either with a falsy (success) <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a>, or with a truthy (fail) one. If the op does not complete, and one invokes the <code>*this</code> dtor, then <code>F()</code> is invoked at dtor time with a particular operation-aborted <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a>.</p>
<p >That said, unlike with (say) <a class="el" href="classipc_1_1transport_1_1Native__socket__stream__acceptor.html" title="A server object that binds to a Shared_name and listens for incoming Native_socket_stream connect att...">transport::Native_socket_stream_acceptor</a> &ndash; and many other classes in <a class="el" href="namespaceipc.html" title="Catch-all namespace for the Flow-IPC project: A library/API in modern C++17 providing high-performanc...">ipc</a> and boost.asio &ndash; the failure of a given <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> does <em>not</em> formally hose <code>*this</code>. Formally, other <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>, including future ones, may succeed. Rationale:</p><ul>
<li>The high-level nature of this class is such that it seemed important to not disregard failed incoming connect attempts by simply not emitting them. The user might monitor/report based on the nature of each problematic one. In particular, log-in failures are of interest w/r/t safety + security.</li>
<li>Given that point, there is no reason to necessarily hose the entire IPC framework for this process (as a server) due to one badly behaving opposing client.</li>
<li>Is is unlikely that a Unix domain socket listener will fail, if it was able to begin listening. So post-ctor problems are unlikely to occur strictly before the log-in exchange procedure.</li>
</ul>
<p >Informally there are a few ways one could deal with each given error.</p><ul>
<li>Simply treating <em>any</em> failed <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> as <code>*this</code>-hosing may well be reasonable. If something went wrong, perhaps it is safest to exit and let the daemon restart in hopes things will start working.</li>
<li>Alternatively one can look for particular <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> values. If it has to do with log-in continue trying <code><a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a></code>s &ndash; perhaps up to a certain number of failures. If it's something not specifically explainable, revert to the previous bullet point (die, restart). The possible <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> values emitted by <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> are documented in its doc header.</li>
</ul>
<p >As of this writing I (ygoldfel) lack sufficient data in the field to make certain pronouncements.</p>
<h3>Relationship with <a class="el" href="structipc_1_1session_1_1Server__app.html" title="An App that is used as a server in at least one client-server IPC split.">Server_app</a> and <a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a>; relationship with file system</h3>
<p >This class operates at quite a high level; there should be (outside of test/debug) only on of them in a process. There are some important relationships to understand:</p><ul>
<li>This process must be invoked consistently with the description in <a class="el" href="structipc_1_1session_1_1Server__app.html" title="An App that is used as a server in at least one client-server IPC split.">Server_app</a> as passed to its ctor. See <a class="el" href="structipc_1_1session_1_1Server__app.html" title="An App that is used as a server in at least one client-server IPC split.">Server_app</a> (and therefore <a class="el" href="structipc_1_1session_1_1App.html" title="A description of an application in this ipc::session inter-process communication universe.">App</a>) doc header. In particular its <a class="el" href="structipc_1_1session_1_1App.html#ae82a8635858664720c8546e468f8090b" title="Absolute, lexically normalized canonical path to the executable entity (which is not a directory),...">App::m_exec_path</a>, <a class="el" href="structipc_1_1session_1_1App.html#a9e32297579603f2d96616976474d0246" title="The application must run as this user ID (UID). Files and other shared resources shall have this owne...">App::m_user_id</a>, <a class="el" href="structipc_1_1session_1_1App.html#a78bb1e984835f429fd44869a83f4b093" title="The application must run as this group ID (GID). Files and other shared resources shall have this own...">App::m_group_id</a> must be consistent with reality.</li>
<li>The <a class="el" href="structipc_1_1session_1_1Client__app.html#add718cbf6aa1d2abb26fbadcc974a7bd" title="Suggested type for storing master repository or all Client_appss. See App doc header for discussion.">Client_app::Master_set</a> of all <code><a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a></code>s must be equal between all applications (this one and the potential client apps included) in the relevant IPC universe &ndash; equal by value and therefore with the same key set (key = <a class="el" href="structipc_1_1session_1_1App.html#a8e67b57829fe43a122a23c699b5de8fd" title="Brief application name, readable to humans and unique across all other applications&#39; names; used both...">App::m_name</a>).</li>
<li>Similarly for <a class="el" href="structipc_1_1session_1_1Server__app.html#a1fc9e403e3b5c89a4cd328da829590a4" title="Suggested type for storing master repository or all Server_appss. See App doc header for discussion.">Server_app::Master_set</a> of all <code><a class="el" href="structipc_1_1session_1_1Server__app.html" title="An App that is used as a server in at least one client-server IPC split.">Server_app</a></code>s.</li>
<li><a class="el" href="structipc_1_1session_1_1Server__app.html#a12df649b33893270afeac7240a571633" title="A given Client_app (as identified by its distinct App::m_name) may request to establish an IPC sessio...">Server_app::m_allowed_client_apps</a> shall list all <code><a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a></code>s that may indeed open sessions against this application. Any other attempts will be rejected.<ul>
<li>Furthermore each given client app instance (process) will need to know certain address information about this server process so as to connect to the right guy (not just application but instance &ndash; e.g., to not connect to some old/dying/zombified instance). While details are intentionally internal there is an interaction with the file system that you should know: The datum internally known as the <em>server app namespace</em> is the key thing that varies from instance to instance. It is, in fact, the PID (process ID) which has good uniqueness properties. This is saved in the so-called Current Namespace Store (CNS) which is simply a PID file, a fairly typical construct in Unix daemons. Therefore:<ul>
<li><a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> writes this in its ctor.</li>
<li>The name is, as of this writing, X.pid, where X is <a class="el" href="structipc_1_1session_1_1App.html#a8e67b57829fe43a122a23c699b5de8fd" title="Brief application name, readable to humans and unique across all other applications&#39; names; used both...">Server_app::m_name</a>.</li>
<li>The location is either a sensible default (/var/run as of this writing) or an override path <a class="el" href="structipc_1_1session_1_1Server__app.html#a4fa3317f8c57042789940be94f872500" title="Absolute path to the directory (without trailing separator) in the file system where kernel-persisten...">Server_app::m_kernel_persistent_run_dir_override</a>. (Reminder: the same <code><a class="el" href="structipc_1_1session_1_1Server__app.html" title="An App that is used as a server in at least one client-server IPC split.">Server_app</a></code>s, by value, must be registered in all processes, whether client or server or both. Hence this override will be agreed-upon on both sides.)</li>
<li><a class="el" href="classipc_1_1session_1_1Client__session__mv.html#ab971ea979200828d572638c60d7d9f44" title="To be invoked in NULL state only, and not as-if default-cted, it synchronously and non-blockingly att...">Client_session::sync_connect()</a> shall check this file immediately to know to which server process &ndash; <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> &ndash; to connect.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p >As of this writing we expect <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> to be in charge of maintaining the process's only PID file, in the sense that a typical daemon is expected to maintain a general-use PID file, with the usual format (where the file contains a decimal encoding of the PID plus a newline). If this is not acceptable &ndash; i.e., we don't want the <a class="el" href="namespaceipc.html" title="Catch-all namespace for the Flow-IPC project: A library/API in modern C++17 providing high-performanc...">ipc</a> system to "step" on some other mechanism for PID files already in use &ndash; then the location may be tweaked, at least via <a class="el" href="structipc_1_1session_1_1Server__app.html#a4fa3317f8c57042789940be94f872500" title="Absolute path to the directory (without trailing separator) in the file system where kernel-persisten...">Server_app::m_kernel_persistent_run_dir_override</a> or possibly with a different default than the current choice (/var/run).</p>
<h3>Thread safety; handler invocation</h3>
<p >After construction of <code>*this</code>, concurrent access to API methods and the dtor is not safe, unless all methods being invoked concurrently are <code>const</code>.</p>
<p >You <em>may</em> invoke <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> directly from within another <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>-passed handler. (Informally we suggest you post all real handling onto your own thread(s).)</p>
<p >However: <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>-passed user handlers may be invoked <em>concurrently to each other</em> (if 2+ <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>s are outstanding). It is your responsibility, then, to ensure you do not invoke 2+ <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>s concurrently. (One way is to only have only 1 outstanding at any given time. Another is to post all handling on your own thread. Really informally we'd say it's best to do both.)</p>
<h3>Subtlety about "FIFO order" w/r/t <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a></h3>
<p >Above we promise that <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> shall emit ready <code>Server_sessions</code>s in "FIFO" order. The following expands on that, for completeness, even though it is unlikely a typical user will care. The FIFO order is subtly different from that in, say, <code>Native_socket_stream_acceptor</code> or boost.asio's <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66" title="Short-hand for boost.asio Unix domain stream-socket acceptor (listening guy) socket.">transport::asio_local_stream_socket::Acceptor</a>. To wit:</p>
<p >Suppose async-accept request R1 was followed by R2. As a black box, it is possible that the handler for R2 will fire before the handler for R1. I.e., the "first out" refers to something different than the order of emission. Rather: each given request R consists of 2 steps internally (listed here in the public section only for exposition):</p><ol type="1">
<li>Accept a Unix domain socket connection. Immediately upon it being accepted:</li>
<li>Execute a log-in exchange on that connection, including things like <a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a> identification and verification and a session token thing.</li>
</ol>
<p >The "FIFO order" refers to the first step. Request R1 shall indeed handle the first incoming socket connection; R2 the second: first-come, first-served. However, the log-in exchange must still occur. In practice this should be quite quick: Client_session will immediately ping us, and we'll ping them back, and that's that. However, it is possible that (for whatever reason) R2 will win the race against R1 despite a head start for the latter. Therefore, it won't look quite like FIFO, though probably it will &ndash; and if not, then close enough.</p>
<p >Rationale: Honestly: It really has to do with simplicity of implementation (discussed in the impl section below but of little interest to the user and not included in the public-API Doxygen-generated docs). Implementing it that way was simpler and easier to maintain; probably the perf less latent too. The fact that, as a result, the FIFO order might get sometimes switched around did not seem important in practice. Still it is worth remarking upon formally.</p>
<p >Informally: are there any practical concerns about this for the user? It seems unlikely. It is, one supposes, sort-of conceivable that some system would rely on the ordering of incoming sessions being requested to be significant in some larger inter-application algorithm. However, 1, that sounds highly unorthodox to put it mildly (more like an abuse of the <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> system's versus its intended usefulness); and 2, even then one could then simply issue <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> R2 upon the success of <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> R1, if an ordering guarantee is really required.</p>
<h3>Implementation</h3>
<p >Internally <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> is really its <code>private</code> base: <a class="el" href="classipc_1_1session_1_1Session__server__impl.html" title="Internal class template comprising API/logic common to every Session_server variant,...">Session_server_impl</a> parameterized on the vanilla <a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59" title="Short-hand for the concrete Server_session-like type emitted by async_accept().">Server_session_obj</a> it produces. See impl notes for that internal class template. 100% of the work done by <code>*this</code> is done by that base. Why does the base exist then? Answer: to implement <a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a> variants with added capabilities, including the capability of producing non-vanilla <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a> variants. For example: <a class="el" href="classipc_1_1session_1_1shm_1_1classic_1_1Session__server.html" title="This is to vanilla Session_server what shm::classic::Server_session is to vanilla Server_session: it ...">shm::classic::Session_server</a>:</p><ul>
<li>emits <a class="el" href="classipc_1_1session_1_1shm_1_1classic_1_1Server__session.html" title="Identical to session::Server_session in every way, except that it makes available two SHM arenas,...">shm::classic::Server_session</a> which is like <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc" title="A vanilla Server_session with no optional capabilities.">Server_session</a> but with its own per-session boost.ipc.shm SHM pool-based arena;</li>
<li>and which also sets up a per-Client_app SHM arena in a boost.ipc.shm SHM pool, for each new distinct <a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a> to start a session (it creates it if needed by name; and keeps handle open; it's an atomic operation).</li>
</ul>
<p >As for this class template, though, we add no such things, because we:</p><ul>
<li>pass-through a no-op <code>per_app_setup_func()</code> that always yields falsy <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a>;</li>
<li>emit vanilla Server_session (<a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59" title="Short-hand for the concrete Server_session-like type emitted by async_accept().">Server_session_obj</a>). </li>
</ul>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">S_MQ_TYPE_OR_NONE</td><td>Emitted <code>Server_session</code>s shall have the concrete typed based on this value for <code>S_MQ_TYPE_OR_NONE</code>. See <a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59" title="Short-hand for the concrete Server_session-like type emitted by async_accept().">Server_session_obj</a>. </td></tr>
    <tr><td class="paramname">S_TRANSMIT_NATIVE_HANDLES</td><td>Emitted <code>Server_session</code>s shall have the concrete typed based on this value for <code>S_TRANSMIT_NATIVE_HANDLES</code>. See <a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59" title="Short-hand for the concrete Server_session-like type emitted by async_accept().">Server_session_obj</a>. </td></tr>
    <tr><td class="paramname">Mdt_payload</td><td>Emitted <code>Server_session</code>s shall have the concrete typed based on this value for <code>Mdt_payload</code>. See <a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59" title="Short-hand for the concrete Server_session-like type emitted by async_accept().">Server_session_obj</a>. In addition the same type may be used for <code>mdt_from_cli_or_null</code> (and srv-&gt;cli counterpart) in <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>. (Recall that you can use a capnp-<code>union</code> internally for various purposes.) </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00193">193</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>
</div><h2 class="groupheader">Member Typedef Documentation</h2>
<a id="a6dea741c32a771532a884ffbc0826bb3" name="a6dea741c32a771532a884ffbc0826bb3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6dea741c32a771532a884ffbc0826bb3">&#9670;&nbsp;</a></span>Channels</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::Channels =  typename Impl::Channels</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for <a class="el" href="classipc_1_1session_1_1Session__mv.html#af87da439644b2afd73d6a13d97e7985f" title="Container (vector&lt;&gt;) of Channel_obj.">Session_mv::Channels</a>. </p>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00219">219</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="a88662c940c51cbaad4dd2cc8af87b147" name="a88662c940c51cbaad4dd2cc8af87b147"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a88662c940c51cbaad4dd2cc8af87b147">&#9670;&nbsp;</a></span>Impl</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::Impl =  <a class="el" href="classipc_1_1session_1_1Session__server__impl.html">Session_server_impl</a> &lt;<a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a>&lt;S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload&gt;, <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc">Server_session</a>&lt;S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload&gt; &gt;</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Short-hand for our base/core impl. </p>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00202">202</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="a86e894429b8568458aa20f3ba814434d" name="a86e894429b8568458aa20f3ba814434d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a86e894429b8568458aa20f3ba814434d">&#9670;&nbsp;</a></span>Mdt_builder</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::Mdt_builder =  typename <a class="el" href="classipc_1_1session_1_1Session__mv.html#af10f452e602e4ea7389c6a77dd9a0f88">Server_session_obj::Mdt_builder</a></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Metadata builder type passed to <code>mdt_load_func()</code> in advanced <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload. </p>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00216">216</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="aa19b9057ac2d873b5989b6213a9e6f82" name="aa19b9057ac2d873b5989b6213a9e6f82"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa19b9057ac2d873b5989b6213a9e6f82">&#9670;&nbsp;</a></span>Mdt_reader_ptr</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::Mdt_reader_ptr =  typename Impl::Mdt_reader_ptr</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for <a class="el" href="classipc_1_1session_1_1Session__mv.html#a2b1215fb0c9738b9fcfbb337d23c43df" title="Implements Session API per contract.">Session_mv::Mdt_reader_ptr</a>. </p>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00213">213</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="a4140ba69205b68aec322ad834f4c8d59" name="a4140ba69205b68aec322ad834f4c8d59"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4140ba69205b68aec322ad834f4c8d59">&#9670;&nbsp;</a></span>Server_session_obj</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::Server_session_obj =  <a class="el" href="namespaceipc_1_1session.html#ab01d5bce0ab2f3435ca9dd88d27609dc">Server_session</a>&lt;S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for the concrete <code>Server_session</code>-like type emitted by <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>. </p>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00210">210</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a948ef778f6dd521e0f7632e9f7e06aa7" name="a948ef778f6dd521e0f7632e9f7e06aa7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a948ef778f6dd521e0f7632e9f7e06aa7">&#9670;&nbsp;</a></span>Session_server()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::Session_server </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structipc_1_1session_1_1Server__app.html">Server_app</a> &amp;&#160;</td>
          <td class="paramname"><em>srv_app_ref</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structipc_1_1session_1_1Client__app.html#add718cbf6aa1d2abb26fbadcc974a7bd">Client_app::Master_set</a> &amp;&#160;</td>
          <td class="paramname"><em>cli_app_master_set_ref</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructor: immediately begins listening for incoming session-open attempts from allowed clients. </p>
<p >This will write to the CNS (PID file) and then listen on Unix domain server socket whose abstract address is based off its contents (as explained in the class doc header).</p>
<p >If either step fails (file error, address-bind error being the most likely culprits), an error is emitted via normal Flow error semantics. If this occurs, via the non-exception-throwing invocation style, then you must not call <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a>; or behavior is undefined (assertion may trip).</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for logging subsequently. </td></tr>
    <tr><td class="paramname">srv_app_ref</td><td>Properties of this server application. The address is copied; the object is not copied. </td></tr>
    <tr><td class="paramname">cli_app_master_set_ref</td><td>The set of all known <code><a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a></code>s. The address is copied; the object is not copied. Technically, from our POV, it need only list the <code><a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a></code>s whose names are in <code>srv_app_ref.m_allowed_client_apps</code>. Refer to <a class="el" href="structipc_1_1session_1_1App.html" title="A description of an application in this ipc::session inter-process communication universe.">App</a> doc header for best practices on maintaining this master list in practice. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code>flow::Error_code</code> docs for error reporting semantics. <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated: interprocess-mutex-related errors (probably from boost.interprocess) w/r/t writing the CNS (PID file); file-related system errors w/r/t writing the CNS (PID file) (see class doc header for background); errors emitted by <a class="el" href="classipc_1_1transport_1_1Native__socket__stream__acceptor.html" title="A server object that binds to a Shared_name and listens for incoming Native_socket_stream connect att...">transport::Native_socket_stream_acceptor</a> ctor (see that ctor's doc header; but note that they comprise name-too-long and name-conflict errors which <a class="el" href="namespaceipc_1_1session.html" title="Flow-IPC module providing the broad lifecycle and shared-resource organization – via the session conc...">ipc::session</a> specifically exists to avoid, so you need not worry about even the fact there's an abstract Unix domain socket address involved). </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00468">468</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="ae9c7c3132edba73bfad5d5a90722e813" name="ae9c7c3132edba73bfad5d5a90722e813"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae9c7c3132edba73bfad5d5a90722e813">&#9670;&nbsp;</a></span>~Session_server()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::~<a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a> </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">default</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Destroys this acceptor which will stop listening in the background and cancel any pending completion handlers by invoking them ASAP with <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fafe29343445a7bf167cc186a44bd2c6ed" title="Async completion handler is being called prematurely, because underlying object is shutting down,...">session::error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER</a>. </p>
<p >Subtlety: expect <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fafe29343445a7bf167cc186a44bd2c6ed" title="Async completion handler is being called prematurely, because underlying object is shutting down,...">session::error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER</a>, not <a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297afe29343445a7bf167cc186a44bd2c6ed" title="Async completion handler is being called prematurely, because underlying object is shutting down,...">transport::error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER</a>, regardless of the fact that internally a <a class="el" href="classipc_1_1transport_1_1Native__socket__stream__acceptor.html" title="A server object that binds to a Shared_name and listens for incoming Native_socket_stream connect att...">transport::Native_socket_stream_acceptor</a> is used.</p>
<p >You must not call this from directly within a completion handler; else undefined behavior.</p>
<p >Each pending completion handler will be called from an unspecified thread that is not the calling thread. Any associated captured state for that handler will be freed shortly after the handler returns.</p>
<p >We informally but very strongly recommend that your completion handler immediately return if the <code>Error_code</code> passed to it is <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fafe29343445a7bf167cc186a44bd2c6ed" title="Async completion handler is being called prematurely, because underlying object is shutting down,...">error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER</a>. This is similar to what one should do when using boost.asio and receiving the conceptually identical <code>operation_aborted</code> error code to an <code>async_...()</code> completion handler. In both cases, this condition means, "we have decided to shut this thing down,
so the completion handlers are simply being informed of this." </p>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="aee11a4a3e305bd3aa330f99fe5a9c509" name="aee11a4a3e305bd3aa330f99fe5a9c509"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aee11a4a3e305bd3aa330f99fe5a9c509">&#9670;&nbsp;</a></span>async_accept() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
<div class="memtemplate">
template&lt;typename Task_err , typename N_init_channels_by_srv_req_func , typename Mdt_load_func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::async_accept </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59">Server_session_obj</a> *&#160;</td>
          <td class="paramname"><em>target_session</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classipc_1_1session_1_1Session__server.html#a6dea741c32a771532a884ffbc0826bb3">Channels</a> *&#160;</td>
          <td class="paramname"><em>init_channels_by_srv_req</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classipc_1_1session_1_1Session__server.html#aa19b9057ac2d873b5989b6213a9e6f82">Mdt_reader_ptr</a> *&#160;</td>
          <td class="paramname"><em>mdt_from_cli_or_null</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classipc_1_1session_1_1Session__server.html#a6dea741c32a771532a884ffbc0826bb3">Channels</a> *&#160;</td>
          <td class="paramname"><em>init_channels_by_cli_req</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">N_init_channels_by_srv_req_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>n_init_channels_by_srv_req_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Mdt_load_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>mdt_load_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_done_func</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Identical to the simpler <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload but offers added advanced capabilities: metadata exchange; initial-channel opening. </p>
<p >The other overload is identical to <code>async_accept(target_session, nullptr, nullptr, nullptr, ...N/A..., NO_OP_FUNC, on_done_func)</code> (where <code>NO_OP_FUNC()</code> no-ops) and requires the opposing <code>sync_connect()</code> to similarly not use the corresponding features.</p>
<p >The advanced capabilities complement/mirror the ones on <a class="el" href="classipc_1_1session_1_1Client__session__mv.html#ab971ea979200828d572638c60d7d9f44" title="To be invoked in NULL state only, and not as-if default-cted, it synchronously and non-blockingly att...">Client_session_mv::sync_connect()</a> (advanced overload); see its doc header first. Then come back here. The same mechanisms underly the following; but due to client-server asymmetry the API is somewhat different.</p>
<h3>Server-&gt;client metadata exchange</h3>
<p >Server may wish to provide information in some way, but without a structured channel &ndash; or any channel &ndash; yet available, this provides an opportunity to do so in a structured way with a one-off message available at session open, together with the opposing <a class="el" href="classipc_1_1session_1_1Session.html" title="A documentation-only concept defining the local side of an IPC conversation (session) with another en...">Session</a> object itself.</p>
<p >The metadata payload you may wish to load to emit to the opposing <code><a class="el" href="classipc_1_1session_1_1Client__session__mv.html#ab971ea979200828d572638c60d7d9f44" title="To be invoked in NULL state only, and not as-if default-cted, it synchronously and non-blockingly att...">Client_session::sync_connect()</a></code> may depend on the following information available <em>during</em> the session-open procedure, namely upon receiving (internally) the log-in request from the client side:</p><ul>
<li>the <a class="el" href="structipc_1_1session_1_1Client__app.html" title="An App that is used as a client in at least one client-server IPC split.">Client_app</a> that wishes to open the session;</li>
<li>how many init-channels the client is requesting be opened (see below);</li>
<li>the client-&gt;Server metadata (see below).</li>
</ul>
<p >Thus supply <code>Mdt_load_func mdt_load_func</code> arg which takes all 3 of these data, plus a blank capnp <code>Mdt_payload</code> structure to fill; and loads the latter as desired.</p>
<p >To omit using this feature do nothing in <code>mdt_load_func()</code>. (The other <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload provides such a no-op function.) Suggest this value in that case: <code>[](auto&amp;&amp;...) {}</code>.</p>
<h3>Client-&gt;server metadata exchange</h3>
<p >This is the reverse of the above. Whatever the opposing client chose to supply as client-&gt;server metadata shall be deserializable at <code>*mdt_from_cli_or_null</code> once (and if) <code>on_done_func(Error_code())</code> (successful accept) fires. If <code>mdt_from_cli_or_null</code> is null, the cli-&gt;srv metadata shall be ignored.</p>
<h3>Init-channels by server request</h3>
<p >Once the session is open, open_channel() and the on-passive-open handler may be used to open channels at will. In many use cases, however, a certain number of channels is required immediately before work can really begin (and, frequently, no further channels are even needed). For convenience (to avoid asynchrony/boiler-plate) the init-channels feature will pre-open a requested # of channels making them available right away, together with the freshly-open session &ndash; to both sides.</p>
<p >The server may request 0 or more init-channels. They shall be opened and placed into <code>*init_channels_by_srv_req</code>. The number of channels requested may depend on the 3 piece of info outlined above in "Server-&gt;client metadata exchange." Thus supply <code>N_init_channels_by_srv_req_func n_init_channels_by_srv_req_func</code> arg which takes all 3 of these data and returns the <code>size_t</code> channel count (possibly 0). The resulting channels shall be loaded into <code>*init_channels_by_srv_req</code> before successful <code>on_done_func()</code> execution.</p>
<p >If and only if <code>n_init_channels_by_srv_req_func()</code> would always return 0, you may provide a null <code>init_channels_by_srv_req</code>. <code>n_init_channels_by_srv_req_func</code> will then be ignored. Suggest this value in that case: <code>[](auto&amp;&amp;...) -&gt; size_t { return 0; }</code></p>
<h3>Init-channels by client request</h3>
<p >This is the reverse of the above. The opposing side shall request 0 or more init-channels-by-client-request; that number of channels shall be opened; and they will be placed into <code>*init_channels_by_cli_req</code> which shall be <code>-&gt;resize()</code>d accordingly, once (and if) <code>on_done_func(Error_code())</code> (successful connect) fires.</p>
<p ><code>init_channels_by_srv_cli</code> being null is allowed, but only if the opposing server requests 0 init-channels-by-server-request. Otherwise an error shall be emitted (see below).</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Task_err</td><td>See other <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload. </td></tr>
    <tr><td class="paramname">N_init_channels_by_srv_req_func</td><td>See above: function type matching signature <code>size_t F(const Client_app&amp;, size_t n_init_channels_by_cli_req, Mdt_reader_ptr&amp;&amp; mdt_from_cli)</code>. </td></tr>
    <tr><td class="paramname">Mdt_load_func</td><td>See above: function type matching signature <code>void F(const Client_app&amp;, size_t n_init_channels_by_cli_req, Mdt_reader_ptr&amp;&amp; mdt_from_cli,
                Mdt_builder* mdt_from_srv)</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target_session</td><td>See other <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload. </td></tr>
    <tr><td class="paramname">init_channels_by_srv_req</td><td>See above: null or pointer to container of <code>Channel_obj</code> which shall be <code>.clear()</code>ed and replaced by a container of PEER-state <code>Channel_obj</code> on success the number being determined by <code>n_init_channels_by_srv_req_func()</code>. null is treated as-if <code>n_init_channels_by_srv_req_func() == 0</code> for any input. </td></tr>
    <tr><td class="paramname">mdt_from_cli_or_null</td><td>See above: null or pointer to <code>Reader</code> of metadata which shall be set for access on success. </td></tr>
    <tr><td class="paramname">init_channels_by_cli_req</td><td>See above: null or pointer to container of <code>Channel_obj</code> which shall be <code>.clear()</code>ed and replaced by a container of PEER-state <code>Channel_obj</code> on success the number being specified by the opposing (client) side. The number may be zero. null is allowed if and only if the number is zero; otherwise <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fac416e988563e44bf15fc6a81743eef53" title="User called an API with 1 or more arguments against the API spec.">error::Code::S_INVALID_ARGUMENT</a> is emitted. </td></tr>
    <tr><td class="paramname">n_init_channels_by_srv_req_func</td><td>See <code>N_init_channels_by_srv_req_func</code>. Ignored on null <code>init_channels_by_srv_req</code>. </td></tr>
    <tr><td class="paramname">mdt_load_func</td><td>See <code>Mdt_load_func</code>. </td></tr>
    <tr><td class="paramname">on_done_func</td><td>See other <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload. Note the above target (pointer) args are touched only if falsy <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> is passed to this handler. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00503">503</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="a13887cd64912bb5f5675e2817ff8435f" name="a13887cd64912bb5f5675e2817ff8435f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a13887cd64912bb5f5675e2817ff8435f">&#9670;&nbsp;</a></span>async_accept() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
<div class="memtemplate">
template&lt;typename Task_err &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::async_accept </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1session_1_1Session__server.html#a4140ba69205b68aec322ad834f4c8d59">Server_session_obj</a> *&#160;</td>
          <td class="paramname"><em>target_session</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_done_func</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Asynchronously awaits for an opposing Client_session to request session establishment and calls <code>on_done_func()</code>, once the connection occurs and log-in exchange completes, or an error occurs, in the former case move-assigning an almost-PEER-state Server_session object to the passed-in Server_session <code>*target_session</code>. </p>
<p ><code>on_done_func(Error_code())</code> is called on success. <code>on_done_func(E)</code>, where <code>E</code> is a non-success error code, is called otherwise. In the latter case <code>*this</code> may continue operation, and further <code><a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a></code>s may succeed. See class doc header regarding error handling.</p>
<p >Multiple <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> calls can be queued while no session-open is pending; they will grab incoming connections in FIFO fashion as they arrive, but log-ins may race afterwards, resulting in not-quite-FIFO emission via handler. See class doc header regarding FIFO ordering.</p>
<p >The aforementioned Server_session generated and move-assigned to <code>*target_session</code> on success shall inherit <code>this-&gt;get_logger()</code> as its <code>-&gt;get_logger()</code>.</p>
<p ><code>on_done_func()</code> shall be called from some unspecified thread, not the calling thread <em>and possibly concurrently with other such completion handlers</em>. Your implementation must be non-blocking. Informally we recommend you place the true on-event logic onto some task loop of your own; so ideally it would consist of essentially a single <code>post(F)</code> statement of some kind.</p>
<p >You must not call this from directly within a completion handler; else undefined behavior.</p>
<p ><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated and passed to <code>on_done_func()</code>: <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fafe29343445a7bf167cc186a44bd2c6ed" title="Async completion handler is being called prematurely, because underlying object is shutting down,...">session::error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER</a> (destructor called, canceling all pending ops; spiritually identical to <code>boost::asio::error::operation_aborted</code>), other system codes most likely from <code>boost::asio::error</code> or <code>boost::system::errc</code> (but never would-block), indicating the underlying <a class="el" href="classipc_1_1transport_1_1Native__socket__stream__acceptor.html" title="A server object that binds to a Shared_name and listens for incoming Native_socket_stream connect att...">transport::Native_socket_stream_acceptor</a> is hosed for that specific reason, those returned by <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html#af63671c0e30d39d3460331c4dd3742b2" title="OS-reported process credential (PID, etc.) info about the other connected peer&#39;s process,...">transport::Native_socket_stream::remote_peer_process_credentials()</a>, those emitted by <a class="el" href="classipc_1_1transport_1_1struc_1_1Channel.html#ae645cb58ad9ea6374970f1f32c5da448" title="In the synchronous/non-blocking manner of Blob_sender::send_blob() or Native_handle_sender::send_nati...">transport::struc::Channel::send()</a>, those emitted by <a class="el" href="classipc_1_1transport_1_1struc_1_1Channel.html" title="Owning and wrapping a pre-connected transport::Channel peer (an endpoint of an established channel ov...">transport::struc::Channel</a> via on-error handler (most likely <a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297aad44f87d53255ba573d57086dfeab805" title="Will not receive message: either opposing user sent graceful-close via API.">transport::error::Code::S_RECEIVES_FINISHED_CANNOT_RECEIVE</a> indicating graceful shutdown of opposing process coincidentally during log-in procedure, prematurely ending session while it was starting), <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2faa195e468548ba9602c27590f2d6d49f0" title="Session master channel: log-in as server: client identifies self as unknown client-app or one that is...">error::Code::S_SERVER_MASTER_LOG_IN_REQUEST_CLIENT_APP_DISALLOWED_OR_UNKNOWN</a>, <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fa3f305ed5a242f067c9116216c0674264" title="Session master channel: log-in as server: client application-level process credentials (UID,...">error::Code::S_SERVER_MASTER_LOG_IN_REQUEST_CLIENT_APP_INCONSISTENT_CREDS</a>, <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fac734bd48bbfe30867f627363a8d5afc4" title="Session master channel: log-in as server: opposing client&#39;s compile-time type config differs from loc...">error::Code::S_SERVER_MASTER_LOG_IN_REQUEST_CONFIG_MISMATCH</a>, <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fac416e988563e44bf15fc6a81743eef53" title="User called an API with 1 or more arguments against the API spec.">error::Code::S_INVALID_ARGUMENT</a> (other side expected other <a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a> overload with non-null <code>init_channels_by_cli_req</code> arg), <a class="el" href="namespaceipc_1_1session_1_1error.html#a0708d4bec9ae853f4d7e3d7822fc8f2fa10d32cf1382fb003f09a6df2da408574" title="Session channel opening: Server peer is responsible for low-level resource acquisition but failed to ...">error::Code::S_SESSION_OPEN_CHANNEL_SERVER_CANNOT_PROCEED_RESOURCE_UNAVAILABLE</a> (unable to acquire init-channel resources &ndash; as of this writing MQ-related ones).</p>
<h3>Error handling discussion</h3>
<p >See class doc header regarding error handling, then come back here. The last 3 specific <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> values listed can be considered, informally, individual misbehavior on the part of the opposing client process. While indicating potentially serious misconfiguration in the system, surely to be investigated ASAP, it is conceivable to continue attempting further <code><a class="el" href="classipc_1_1session_1_1Session__server.html#a13887cd64912bb5f5675e2817ff8435f" title="Asynchronously awaits for an opposing Client_session to request session establishment and calls on_do...">async_accept()</a></code>s.</p>
<p >Do note, though, that this is not a network client-server situation. That is, probably, one should not expect lots of &ndash; or any &ndash; such problems in a smoothly functioning IPC universe on a given production server machine. E.g., there could be a security problem, or perhaps more likely there's a software mismatch between client and server w/r/t their master <a class="el" href="structipc_1_1session_1_1App.html" title="A description of an application in this ipc::session inter-process communication universe.">App</a> sets. Your software deployment story may or may not be designed to allow for this as a transient condition during software upgrades and such.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Task_err</td><td>Handler type matching signature of <code>flow::async::Task_asio_err</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target_session</td><td>Pointer to Server_session which shall be assigned an almost-PEER-state (open, requires <a class="el" href="classipc_1_1session_1_1Server__session__mv.html#a99097e5aa6883877c74f8a93ebc9f3e1" title="To be invoked by public user upon first obtaining *this: memorizes the given on-error and on-passive-...">Server_session::init_handlers()</a> to enter PEER state) as <code>on_done_func()</code> is called. Not touched on error. </td></tr>
    <tr><td class="paramname">on_done_func</td><td>Completion handler. See above. The captured state in this function object shall be freed shortly upon its completed execution from the unspecified thread. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00482">482</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<a id="a5fac8f78f1ff443db9b46788cae77fc4" name="a5fac8f78f1ff443db9b46788cae77fc4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5fac8f78f1ff443db9b46788cae77fc4">&#9670;&nbsp;</a></span>to_ostream()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void <a class="el" href="classipc_1_1session_1_1Session__server.html">ipc::session::Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt;::to_ostream </td>
          <td>(</td>
          <td class="paramtype">std::ostream *&#160;</td>
          <td class="paramname"><em>os</em></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Prints string representation to the given <code>ostream</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00516">516</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Friends And Related Function Documentation</h2>
<a id="a4556b229bf2bfc3c9eb51af13c47de3d" name="a4556b229bf2bfc3c9eb51af13c47de3d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4556b229bf2bfc3c9eb51af13c47de3d">&#9670;&nbsp;</a></span>operator&lt;&lt;()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;schema::MqType S_MQ_TYPE_OR_NONE, bool S_TRANSMIT_NATIVE_HANDLES, typename Mdt_payload &gt; </div>
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="classipc_1_1session_1_1Session__server.html">Session_server</a>&lt; S_MQ_TYPE_OR_NONE, S_TRANSMIT_NATIVE_HANDLES, Mdt_payload &gt; &amp;&#160;</td>
          <td class="paramname"><em>val</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">related</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Prints string representation of the given <code><a class="el" href="classipc_1_1session_1_1Session__server.html" title="To be instantiated typically once in a given process, an object of this type asynchronously listens f...">Session_server</a></code> to the given <code>ostream</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">val</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html#l00522">522</a> of file <a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a>.</p>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>session/<a class="el" href="session__fwd_8hpp_source.html">session_fwd.hpp</a></li>
<li>session/<a class="el" href="ipc__session_2src_2ipc_2session_2session__server_8hpp_source.html">session_server.hpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu May 2 2024 23:56:39 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
